#ifndef CQ_TIMER_H
#define CQ_TIMER_H

#include "CQ_defines.h"
#include "CQ_signal.h"
#include "CQ_guard.h"
#include "CQ_object.h"
#include "CQ_logger.h"

DEFINE_NAMESPACE_CQ_BEGIN

enum TIMER_TYPE
{
	SINGLE,
	REPEAT
};

class CQTimer : public CQObject
{
public:
	CQTimer()
		: CQObject()
		, m_ms(0)
		, m_guard(nullptr)
		, m_type(REPEAT)
		, m_isStart(false)
	{

	}

	~CQTimer()
	{
		if (m_guard) {
			delete m_guard;
			m_guard = nullptr;
		}
		m_isStart = true;
	}

	void start(int ms, TIMER_TYPE type_ = REPEAT)
	{
		m_type = type_;
		m_ms = ms;
		if (m_guard) {
			delete m_guard;
		}
		m_guard = new CQGuard();
		CQTaskBase* _task = new CQDelayTask(std::bind(&CQTimer::tick, this, *m_guard));
		_task->setTtl(m_ms);
		auto _looper = eventLooper();
		_looper->enqueue(_task);
		m_isStart = true;
	}

	void start()
	{
		start(m_ms);
	}

	bool isStrat() const
	{
		return m_isStart;
	}

	void stop()
	{
		m_isStart = false;
		delete m_guard;
		m_guard = nullptr;
	}

	void setInterval(int ms)
	{
		m_ms = ms;
	}

	CQ_SIGNAL() timeout;

protected:
	void tick(CQGuard guard)
	{
		if (!m_isStart) {
			return;
		}
		if (guard) {
			CQ_EMIT(timeout);
		}
		else {
			return;
		}
		if (m_type == REPEAT && m_isStart && m_guard) {
			CQTaskBase* _task = new CQDelayTask(std::bind(&CQTimer::tick, this, *m_guard));
			_task->setTtl(m_ms);
			auto _looper = eventLooper();
			_looper->enqueue(_task);
		}
	}

private:
	int m_ms;
	CQGuard* m_guard;
	TIMER_TYPE m_type;
	bool m_isStart;
};

DEFINE_NAMESPACE_CQ_END

#endif // CQ_TIMER_H
